<template>
  <div class="scanner-container">
    <h1>QR Code Scanner</h1>
    <div v-if="isScanning && actualResolution">
      当前分辨率：<strong>{{ actualResolution }}</strong>
    </div>
    <!-- 摄像头选择 -->
    <div v-if="videoDevices.length > 0" class="camera-select">
      <label for="cameraSelect">选择摄像头：</label>
      <select v-model="selectedDeviceIndex" id="cameraSelect">
        <option v-for="(_device, index) in videoDevices" :key="index" :value="index" @click="selectDevice(index)">
          {{ "镜头 " + (index + 1) }}
        </option>
      </select>
    </div>

    <!-- 按钮 -->
    <div class="btn-group">
      <button @click="startScanning" v-if="!isScanning">📷 开始扫描</button>
      <button @click="stopScanning" v-if="isScanning">🛑 停止扫描</button>
    </div>

 
    <p v-if="errorMessage" class="error-text">⚠️ {{ errorMessage }}</p>


    <p class="result-text" style="padding-top: 15px;">
      <!-- <span v-if="issuccess">✅ 结果：</span>
      <input v-model="scannedText" type="text" /> -->
      <v-text-field v-model="scannedText" label="文本" variant="underlined"></v-text-field>
    </p>

    <!-- 视频扫描区域 -->
    <div v-if="isScanning" class="video-wrapper">
      <video ref="videoElement" autoplay playsinline></video>
    </div>

    <!-- 生成二维码 -->
    <div v-if="scannedText" class="qrcode-container">
      <button @click="toggleQRCode">📌 生成二维码</button>
    </div>
  </div>
  <vue-qrcode v-if="showQRCode && scannedText" :value="scannedText" :width="200"></vue-qrcode>
</template>

<script lang="ts" setup>
    import { ref, onMounted, nextTick, onBeforeUnmount, watch } from 'vue';
    import { BrowserMultiFormatReader, BarcodeFormat,  NotFoundException } from '@zxing/library';
    const emit = defineEmits(["saveCameraId"])
    const videoElement = ref<HTMLVideoElement | null>(null);
    const scannedText = ref<string | null>("");
    const errorMessage = ref<string | null>(null);
    const isScanning = ref<boolean>(false);
    const showQRCode = ref<boolean>(false);
    const videoDevices = ref<Array<MediaDeviceInfo>>([]);
    const selectedDeviceId = ref<string>('');
    const selectedDeviceIndex = ref<number>(0);
    const codeReader = ref<BrowserMultiFormatReader | null>(null);
    let mediaStream: MediaStream | null = null;
    const issuccess = ref<boolean>(false);
    const props = defineProps<{
      cameraId: number
    }>()

    const actualResolution = ref<string | null>(null);


    watch(selectedDeviceIndex, (_1, _2) => {
      console.log(selectedDeviceIndex.value)
      selectedDeviceId.value = videoDevices.value[selectedDeviceIndex.value].deviceId;
      emit("saveCameraId", selectedDeviceIndex.value);
    })

    function selectDevice(index: number) {
      console.log("||||||||||||||||||||||||||||||||||||||||||")
      console.log(index)
    }

    /** 获取视频设备列表 */
    const getVideoDevices = async () => {
      try {
        const devices = await navigator.mediaDevices.enumerateDevices();
        videoDevices.value = devices.filter((device) => device.kind === 'videoinput');
        if (videoDevices.value.length === 0) {
          errorMessage.value = '未发现摄像头';
        } else if (!selectedDeviceId.value) {
          if (props.cameraId < videoDevices.value.length) {
            selectedDeviceIndex.value = props.cameraId;
            selectedDeviceId.value = videoDevices.value[selectedDeviceIndex.value].deviceId;
          }
          console.log("---------------")
          console.log(selectedDeviceId.value)
        }
      } catch (err) {
        errorMessage.value = '无法访问摄像头设备';
        console.error(err);
      }
    };

    /** 开始扫码 */
    const startScanning = async () => {
      if (!selectedDeviceId.value) {
        errorMessage.value = '未选择摄像头';
        return;
      }

      isScanning.value = true;
      errorMessage.value = null;
      scannedText.value = null;
      showQRCode.value = false;
      codeReader.value = new BrowserMultiFormatReader();

      const constraints: MediaStreamConstraints = {
        video: { 
          width: { ideal: 1920 },
          height: { ideal: 1080 },
          //audio: false,
          deviceId: { exact: selectedDeviceId.value } 
        },
      };

      try {
        mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
        // 获取当前摄像头的实际分辨率
        const videoTrack = mediaStream.getVideoTracks()[0];
        const settings = videoTrack.getSettings();
        actualResolution.value = `${settings.width} x ${settings.height}`;

        nextTick(() => {
          if (videoElement.value) {
            videoElement.value.srcObject = mediaStream;
            codeReader.value?.decodeFromVideoDevice(selectedDeviceId.value, videoElement.value, (result, error) => {
              if (result) {
                onScanSuccess(result);
              } else if (error) {
                onScanError(error);
              }
            });
          }
        });
      } catch (err: any) {
        errorMessage.value = `摄像头错误: ${err.message}`;
        isScanning.value = false;
      }
    };

    /** 停止扫码 */
    const stopScanning = () => {
      isScanning.value = false;
      if (codeReader.value) codeReader.value.reset();
      if (mediaStream) {
        mediaStream.getTracks().forEach(track => track.stop());
        mediaStream = null;
      }
    };

    /** 扫码成功 */
    const onScanSuccess = (result: any) => {
      errorMessage.value = null; // ✅ 成功后清空错误信息
      // 根据 result.getBarcodeFormat() 来判断扫描的类型
      if (result.getBarcodeFormat() === BarcodeFormat.QR_CODE) {
        console.log('扫描到二维码:', result.getText());
      } else if ([BarcodeFormat.CODE_128, BarcodeFormat.EAN_13, BarcodeFormat.UPC_A].includes(result.getBarcodeFormat())) {
        console.log('扫描到条形码:', result.getText());
      }
      scannedText.value = result.getText();
      issuccess.value = true;
      stopScanning(); // 扫描成功后自动关闭相机
    };

    /** 扫码失败 */
    const onScanError = (error: any) => {
      if (error instanceof NotFoundException) {
        errorMessage.value = '未找到二维码，请对准摄像头';
      } else {
        errorMessage.value = '扫描失败，请重试';
      }
    };

    /** 检查摄像头权限 */
    const checkCameraPermission = async () => {
      try {
        const permission = await navigator.permissions.query({ name: 'camera' as PermissionName });
        if (permission.state === 'denied') {
          errorMessage.value = '摄像头权限被拒绝，请手动开启';
        }
      } catch (err) {
        console.error('权限检查失败:', err);
      }
    };

    /** 切换二维码显示 */
    const toggleQRCode = () => {
      showQRCode.value = !showQRCode.value;
    };

    onMounted(async () => {
      await checkCameraPermission();
      await getVideoDevices();
    });

    onBeforeUnmount(() => {
      stopScanning();
    });
</script>

<style scoped>
/* 页面样式美化 */
.scanner-container {
  max-width: 400px;
  margin: auto;
  text-align: center;
  font-family: Arial, sans-serif;
  background: #f9f9f9;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

h1 {
  font-size: 20px;
  margin-bottom: 10px;
}

.camera-select {
  margin-bottom: 10px;
}

.btn-group {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 10px;
}

button {
  padding: 8px 12px;
  border: none;
  border-radius: 5px;
  background: #007bff;
  color: white;
  cursor: pointer;
  font-size: 14px;
  transition: 0.3s;
}

button:hover {
  background: #0056b3;
}

.result-text {
  font-size: 16px;
  color: #28a745;
  font-weight: bold;
  margin-top: 10px;
}

.error-text {
  font-size: 14px;
  color: red;
  font-weight: bold;
}

.video-wrapper {
  width: 100%;       /* 固定容器宽度 */
  height: 400px;     /* 固定容器高度 */
  overflow: hidden;  /* 隐藏超出的部分 */
  display: flex;
  justify-content: center;
  align-items: center; /* 居中 */
}

video {
  width: 200%;
  height: auto; 
  border-radius: 10px;
  border: 1px solid #ccc;
  transform: scale(1.2); /* 放大1.2倍 */
  object-fit: cover; /* 保持视频比例，裁切超出部分 */
}

.qrcode-container {
  margin-top: 15px;
}

.qrcode-container button {
  background: #28a745;
}

.qrcode-container button:hover {
  background: #218838;
}
</style>
